﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;

//namespace devtm.AutoMapper.CustomCode.Details
//{

//    /// <summary>
//    /// Tree Container
//    /// </summary>
//    public class ModelExplorerTreeContainer : ContainerBase
//    {
//        /// <summary>
//        /// Track the add menu command we created initially.
//        /// </summary>
//        private AddModelElementMenuCommand addModelElementMenuCommand;
//        /// <summary>
//        /// Return the default stock model element image index.
//        /// </summary>
//        private const int DefaultModelElementTreeNodeImageIndex = 0;
//        /// <summary>
//        /// Return the default RoleGroupTreeNode image index in the ImageList
//        /// </summary>
//        private const int DefaultRoleGroupTreeNodeImageIndex = 1;
//        /// <summary>
//        /// Return the default RoleTreeNode image index in the ImageList
//        /// </summary>
//        private const int DefaultRoleTreeNodeImageIndex = 2;
//        /// <summary>
//        /// Element Visitor
//        /// </summary>
//        private IElementVisitor elementVisitor;
//        /// <summary>
//        /// Element Visitor Filter
//        /// </summary>
//        private IElementVisitorFilter elementVisitorFilter;
//        /// <summary>
//        /// Call back function for the generated designer to supply the display name shown in the ModelExplorer
//        /// </summary>
//        private GetModelElementDisplayNameEventHandler getModelElementDisplayNameEventHandler;
//        /// <summary>
//        /// Records the hidden path if there's any
//        /// </summary>
//        private List<List<Guid>> hiddenPaths;
//        /// <summary>
//        /// Records the imagelist used in the treeview 
//        /// </summary>
//        private ImageList imageList;
//        /// <summary>
//        /// DocData
//        /// </summary>
//        private ModelingDocData modelingDocData;
//        /// <summary>
//        /// Table of TreeNodes, hashed by represented Element
//        /// </summary>
//        private Hashtable nodeLookup;
//        /// <summary>
//        /// Model browser
//        /// </summary>
//        private TreeView objectModelBrowser;
//        /// <summary>
//        /// Root Elements
//        /// </summary>
//        private List<ModelElement> rootElements;
//        /// <summary>
//        /// Selection
//        /// </summary>
//        private ISelectionService selectionService;
//        /// <summary>
//        /// Tool Window
//        /// </summary>
//        private IServiceProvider serviceProvider;
//        /// <summary>
//        /// records the corresponding mapping index to determine whetehr we need to show the DomainClass in the tree node (e.g. "foo (Foo)" as 
//        /// the node name
//        /// </summary>
//        private Dictionary<Guid, bool> showDomainClassList;
//        /// <summary>
//        /// The modeling Store to which the explorer is connected (from the docdata)
//        /// </summary>
//        private Store store;
//        /// <summary>
//        /// records the corresponding mapping index for all the domian class info user specified.
//        /// </summary>
//        private List<Guid> typeList;

//        /// <summary>
//        /// Constructor
//        /// </summary>
//        /// <param name="serviceProvider">Service</param>
//        public ModelExplorerTreeContainer(IServiceProvider serviceProvider)
//            : base(serviceProvider)
//        {
//            this.nodeLookup = new Hashtable();
//            this.serviceProvider = serviceProvider;
//            Rectangle borderRectangle = base.BorderRectangle;
//            this.ObjectModelBrowser.Left = borderRectangle.Left + 1;
//            this.ObjectModelBrowser.Top = borderRectangle.Top + 1;
//            this.ObjectModelBrowser.Width = borderRectangle.Width - 1;
//            this.ObjectModelBrowser.Height = borderRectangle.Height - 1;
//            this.ObjectModelBrowser.Visible = true;
//            this.ObjectModelBrowser.Anchor = AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Top;
//            this.ObjectModelBrowser.ShowRootLines = false;
//            this.ObjectModelBrowser.HideSelection = false;
//            base.Controls.Add(this.ObjectModelBrowser);
//            this.ObjectModelBrowser.BeforeCollapse += new TreeViewCancelEventHandler(this.TreeViewBeforeCollapse);
//            this.ObjectModelBrowser.AfterSelect += new TreeViewEventHandler(this.TreeViewAfterSelectEvent);
//            this.ObjectModelBrowser.MouseDown += new MouseEventHandler(this.TreeViewOnMouseDown);
//            this.ObjectModelBrowser.WindowTarget = new SafeWindowTarget(this.serviceProvider, this.ObjectModelBrowser.WindowTarget);
//            this.ObjectModelBrowser.LostFocus += new EventHandler(this.TreeViewLostFocus);
//            this.objectModelBrowser.BorderStyle = BorderStyle.None;
//        }

//        private static void AddCommand(IMenuCommandService menuCommandService, MenuCommand command)
//        {
//            if (menuCommandService.FindCommand(command.CommandID) == null)
//            {
//                menuCommandService.AddCommand(command);
//            }
//        }

//        /// <summary>
//        /// Adds command handlers for commands that appear in the context menu.  Base implementation
//        /// will only add command handlers if a handler is not already registered, to allow derived
//        /// classes to override handling of a particular command.  For this reason, derived classes
//        /// should add commands first before calling the base class.
//        /// </summary>
//        /// <param name="menuCommandService">IMenuCommandService to which commands should be added.</param>
//        public virtual void AddCommandHandlers(IMenuCommandService menuCommandService)
//        {
//            AddCommand(menuCommandService, new DynamicStatusMenuCommand(new EventHandler(this.OnStatusProperties), new EventHandler(this.OnMenuProperties), CommonModelingCommands.Properties));
//            this.addModelElementMenuCommand = new AddModelElementMenuCommand(this, new EventHandler(this.OnStatusAddModelElement), new EventHandler(this.OnMenuAddModelElement));
//            AddCommand(menuCommandService, this.addModelElementMenuCommand);
//            AddCommand(menuCommandService, new DynamicStatusMenuCommand(new EventHandler(this.OnStatusDelete), new EventHandler(this.OnMenuDelete), StandardCommands.Delete));
//            AddCommand(menuCommandService, new DynamicStatusMenuCommand(new EventHandler(this.OnStatusDeleteAll), new EventHandler(this.OnMenuDeleteAll), CommonModelingCommands.ModelExplorerDeleteAll));
//        }

//        /// <summary>
//        /// Method allows the user to associate image with the domainClass object. This allows the user 
//        /// to customize the image used for each type of modelelement.
//        /// </summary>
//        /// <param name="domainClassId">domainclass where the image is assoiciated.</param>
//        /// <param name="treeNodeImage">Image to be used</param>
//        /// <param name="showDomainClassName">to show className right next to the model element name.</param>
//        protected void AddExplorerNodeCustomSetting(Guid domainClassId, Image treeNodeImage, bool showDomainClassName)
//        {
//            if (domainClassId != Guid.Empty)
//            {
//                if (this.showDomainClassList == null)
//                {
//                    this.showDomainClassList = new Dictionary<Guid, bool>();
//                }
//                this.showDomainClassList[domainClassId] = showDomainClassName;
//                if (treeNodeImage != null)
//                {
//                    if (this.imageList == null)
//                    {
//                        this.imageList = new ImageList();
//                        this.imageList.ColorDepth = ColorDepth.Depth32Bit;
//                        this.typeList = new List<Guid>();
//                        this.imageList.Images.Add(Microsoft.VisualStudio.Modeling.Shell.ModelExplorer.ModelExplorer.ModelElementTreeNodeImage);
//                        this.imageList.Images.Add(Microsoft.VisualStudio.Modeling.Shell.ModelExplorer.ModelExplorer.RoleGroupTreeNodeImage);
//                        this.imageList.Images.Add(Microsoft.VisualStudio.Modeling.Shell.ModelExplorer.ModelExplorer.RoleTreeNodeImage);
//                        this.typeList.Add(Guid.Empty);
//                        this.typeList.Add(Guid.Empty);
//                        this.typeList.Add(Guid.Empty);
//                        this.imageList.TransparentColor = Color.Magenta;
//                        this.ObjectModelBrowser.ImageList = this.imageList;
//                    }
//                    int index = this.typeList.IndexOf(domainClassId);
//                    if (index == -1)
//                    {
//                        this.typeList.Add(domainClassId);
//                        this.imageList.Images.Add(treeNodeImage);
//                    }
//                    else
//                    {
//                        this.imageList.Images[index] = treeNodeImage;
//                    }
//                }
//            }
//        }

//        /// <summary>
//        /// Retrns the current collection of Paths (in Guid form) for elements to be hidden from the model explorer.
//        /// </summary>
//        /// <param name="path">A list of guids which indicate a hidden path which we'd like to hide from the model explorer</param>
//        protected void AddHiddenPath(ICollection<Guid> path)
//        {
//            if (path == null)
//            {
//                throw new ArgumentNullException("path");
//            }
//            if ((path.Count & 1) == 0)
//            {
//                throw new InvalidOperationException();
//            }
//            if (this.hiddenPaths == null)
//            {
//                this.hiddenPaths = new List<List<Guid>>();
//            }
//            this.hiddenPaths.Add(new List<Guid>(path));
//        }

//        /// <summary>
//        /// Add Root Element
//        /// </summary>
//        /// <param name="rootElement">Root</param>
//        /// <remarks>The root and its sub-elements will not appear in the explorer until RefreshBrowserView() is called.</remarks>
//        protected void AddRootElement(ModelElement rootElement)
//        {
//            if (this.rootElements == null)
//            {
//                this.rootElements = new List<ModelElement>();
//            }
//            if (!this.rootElements.Contains(rootElement))
//            {
//                this.rootElements.Add(rootElement);
//            }
//        }

//        private bool CanDelete(ModelElement element)
//        {
//            return (((element != null) && !this.RootElements.Contains(element)) && this.ElementOperations.CanDelete(element, new Guid[0]));
//        }

//        /// <summary>
//        /// Determine whether the passed in candidate doc data can be hosted under the container.
//        /// </summary>
//        /// <param name="candidate"></param>
//        /// <returns></returns>
//        /// <remarks>
//        /// Each language has its own Language-specific model explorer tool window. We can't blindly push modelingDocData 
//        /// into the model explorer.
//        /// Each tool window will now have an abstract RootDomainClassId which describes what root element (i.e. language) it can support.
//        /// We can just check the incoming modelingDocData's root element. Only push the new modelingDocData if the tool window
//        /// supports the model.
//        /// </remarks>
//        internal bool CanHostStore(ModelingDocData candidate)
//        {
//            if (candidate == null)
//            {
//                return false;
//            }
//            DomainClassInfo domainClass = candidate.Store.DomainDataDirectory.FindDomainClass(this.RootElementDomainClassId);
//            ModelElement rootElement = candidate.RootElement;
//            DomainClassInfo info2 = (rootElement != null) ? rootElement.GetDomainClass() : null;
//            return (((domainClass != null) && (info2 != null)) && info2.IsDerivedFrom(domainClass));
//        }

//        /// <summary>
//        /// Clear Tree
//        /// </summary>
//        internal void ClearTreeView()
//        {
//            List<ExplorerTreeNode> allNodes = this.GetAllNodes();
//            this.RootNodes.Clear();
//            allNodes.ForEach(delegate(ExplorerTreeNode n)
//            {
//                n.Dispose();
//            });
//            this.nodeLookup.Clear();
//        }

//        /// <summary>
//        /// Create IElementVisitor
//        /// </summary>
//        /// <returns>IElementVisitor</returns>
//        protected virtual IElementVisitor CreateElementVisitor()
//        {
//            return new ExplorerElementVisitor(this);
//        }

//        /// <summary>
//        /// Create IElementVisitorFilter
//        /// </summary>
//        /// <returns>IElementVisitorFilter</returns>
//        protected virtual IElementVisitorFilter CreateElementVisitorFilter()
//        {
//            return new DslModelExplorerFilter(this.hiddenPaths);
//        }

//        /// <summary>
//        /// Extension point for supplying user defined TreeNode.
//        /// </summary>
//        /// <param name="modelElement">model element to be represented by the to be created ModelElementTreeNode in the tree view</param>
//        /// <returns></returns>
//        public virtual ModelElementTreeNode CreateModelElementTreeNode(ModelElement modelElement)
//        {
//            if (modelElement == null)
//            {
//                throw new ArgumentNullException("modelElement");
//            }
//            ModelElementTreeNode node = new ModelElementTreeNode(modelElement);
//            if (this.getModelElementDisplayNameEventHandler != null)
//            {
//                node.getModelElementDisplayName = this.getModelElementDisplayNameEventHandler;
//            }
//            if (this.objectModelBrowser.ImageList != null)
//            {
//                node.DefaultImageIndex = 0;
//            }
//            return node;
//        }

//        /// <summary>
//        /// Extension point for supplying user defined TreeNode which represents role multiplicity 0..* or 1..*
//        /// </summary>
//        /// <param name="targetRoleInfo">DomainRoleInfo to be represented by the to be created RoleGroupTreeNode in the tree view</param>
//        /// <returns></returns>
//        public virtual RoleGroupTreeNode CreateRoleGroupTreeNode(DomainRoleInfo targetRoleInfo)
//        {
//            if (targetRoleInfo == null)
//            {
//                throw new ArgumentNullException("targetRoleInfo");
//            }
//            RoleGroupTreeNode node = new RoleGroupTreeNode(targetRoleInfo);
//            if (this.objectModelBrowser.ImageList != null)
//            {
//                node.DefaultImageIndex = 1;
//            }
//            return node;
//        }

//        /// <summary>
//        /// Extension point for supplying user defined TreeNode which represents role multiplicity 1 or 0..1
//        /// </summary>
//        /// <param name="targetRoleInfo">DomainRoleInfo to be represented by the to be created RoleTreeNode in the tree view</param>
//        /// <returns></returns>
//        public virtual RoleTreeNode CreateRoleTreeNode(DomainRoleInfo targetRoleInfo)
//        {
//            if (targetRoleInfo == null)
//            {
//                throw new ArgumentNullException("targetRoleInfo");
//            }
//            RoleTreeNode node = new RoleTreeNode(targetRoleInfo);
//            if (this.objectModelBrowser.ImageList != null)
//            {
//                node.DefaultImageIndex = 2;
//            }
//            return node;
//        }

//        private void DepthFirstTraversal(TreeNodeCollection nodes, Action<ExplorerTreeNode> op)
//        {
//            foreach (ExplorerTreeNode node in nodes)
//            {
//                this.DepthFirstTraversal(node.Nodes, op);
//                op(node);
//            }
//        }

//        /// <summary>
//        /// Disposes the state of this object.
//        /// </summary>
//        /// <param name="disposing">If this method is called from Dispose (true) or Finalizer (false).</param>
//        protected override void Dispose(bool disposing)
//        {
//            try
//            {
//                if (disposing)
//                {
//                    if (this.objectModelBrowser != null)
//                    {
//                        this.ClearTreeView();
//                        this.objectModelBrowser.Dispose();
//                    }
//                    if (this.imageList != null)
//                    {
//                        this.imageList.Dispose();
//                    }
//                }
//            }
//            finally
//            {
//                this.addModelElementMenuCommand = null;
//                this.objectModelBrowser = null;
//                this.imageList = null;
//                this.showDomainClassList = null;
//                this.typeList = null;
//                this.rootElements = null;
//                base.Dispose(disposing);
//            }
//        }

//        /// <summary>
//        /// Event Handler
//        /// </summary>
//        /// <param name="sender">Sender</param>
//        /// <param name="e">Event args</param>
//        private void ElementEventsEndedEventHandlerImpl(object sender, ElementEventsEndedEventArgs e)
//        {
//            this.RefreshBrowserView();
//        }

//        private bool EnsureVisibleAndSelectElementNode(ModelElement element)
//        {
//            ExplorerTreeNode nodeForElement = this.LookupNodeForElement(element);
//            if (nodeForElement != null)
//            {
//                nodeForElement.EnsureVisible();
//                this.ObjectModelBrowser.SelectedNode = nodeForElement;
//                return true;
//            }
//            return false;
//        }

//        private void ExploreStore(Store newStore)
//        {
//            if (this.store != newStore)
//            {
//                if (this.store != null)
//                {
//                    this.UnsubscribeToImsEvent(this.store);
//                    this.ClearTreeView();
//                }
//                this.store = newStore;
//                if (this.store != null)
//                {
//                    this.RefreshBrowserView();
//                    this.SubscribeToImsEvent(this.store);
//                }
//            }
//        }

//        /// <summary>
//        /// Finds the tree node in the model explorer corresponding to the given ModelElement.
//        /// If the element does not have a corresponding node in the tree, this method returns null.
//        /// </summary>
//        public virtual ExplorerTreeNode FindNodeForElement(ModelElement element)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            return this.LookupNodeForElement(element);
//        }

//        /// <summary>
//        /// Finds all root elements in a store.
//        /// By default this is a list of all orphaned elements, excluding ExtensionElements.
//        /// </summary>
//        /// <param name="store">Store</param>
//        /// <returns>List of root ModelElement objects</returns>
//        protected virtual IList FindRootElements(Store store)
//        {
//            if (store == null)
//            {
//                throw new ArgumentNullException("store");
//            }
//            return (from e in store.ElementDirectory.AllElements
//                    where ((!e.IsDeleted && !(e is ElementLink)) && !(e is ExtensionElement)) && (DomainClassInfo.FindEmbeddingElement(e) == null)
//                    select e).ToList<ModelElement>();
//        }

//        private List<ExplorerTreeNode> GetAllNodes()
//        {
//            List<ExplorerTreeNode> allNodes = new List<ExplorerTreeNode>();
//            this.DepthFirstTraversal(this.RootNodes, delegate(ExplorerTreeNode node)
//            {
//                allNodes.Add(node);
//            });
//            return allNodes;
//        }

//        private IList<ModelElement> GetChildrenOfSelectedRoleGroup()
//        {
//            ExplorerTreeNode selectedNode = this.SelectedNode;
//            if (((selectedNode == null) || (selectedNode.RepresentedRole == null)) || (selectedNode.RepresentedElement != null))
//            {
//                return new List<ModelElement>();
//            }
//            return (from node in selectedNode.Nodes.OfType<ExplorerTreeNode>()
//                    where node.RepresentedElement != null
//                    select node.RepresentedElement).ToList<ModelElement>();
//        }

//        /// <summary>
//        /// Helper method to determine the image index to be used.
//        /// </summary>
//        /// <param name="domainClassInfo"></param>
//        /// <param name="imageIndexPos"></param>
//        /// <param name="showDomainClassName">whether to show the domain class name after the model element name</param>
//        /// <returns>index position to the image (defined in the TreeView.ImageList)</returns>
//        internal void GetExplorerNodeCustomSettings(DomainClassInfo domainClassInfo, out int imageIndexPos, out bool showDomainClassName)
//        {
//            bool flag = false;
//            bool flag2 = false;
//            showDomainClassName = true;
//            imageIndexPos = -1;
//            if (this.imageList == null)
//            {
//                flag = true;
//            }
//            if (this.showDomainClassList == null)
//            {
//                flag2 = true;
//            }
//            DomainClassInfo baseDomainClass = domainClassInfo;
//            do
//            {
//                if (!flag)
//                {
//                    imageIndexPos = this.typeList.IndexOf(baseDomainClass.Id);
//                    flag = imageIndexPos != -1;
//                }
//                if (!flag2)
//                {
//                    flag2 = this.showDomainClassList.TryGetValue(baseDomainClass.Id, out showDomainClassName);
//                }
//                if (flag && flag2)
//                {
//                    break;
//                }
//                baseDomainClass = baseDomainClass.BaseDomainClass;
//            }
//            while (baseDomainClass != null);
//            if (!flag)
//            {
//                imageIndexPos = 0;
//            }
//            if (!flag2)
//            {
//                showDomainClassName = true;
//            }
//        }

//        /// <summary>
//        /// Insert childNode as a new child of parentNode. If parentNode is null, then insert a new root.
//        /// This is the correct way to insert a new node into the tree maintaining its internal state,
//        /// in particular the element to node mapping.
//        /// </summary>
//        /// <param name="parentNode"></param>
//        /// <param name="childNode"></param>
//        /// <returns></returns>
//        public void InsertNode(ExplorerTreeNode parentNode, ExplorerTreeNode childNode)
//        {
//            if (childNode == null)
//            {
//                throw new ArgumentNullException("childNode");
//            }
//            if (childNode.Parent != null)
//            {
//                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Microsoft.VisualStudio.Modeling.Shell.ModelExplorer.ModelExplorer.NodeAlreadyInTree, new object[] { childNode.ToString() }), "childNode");
//            }
//            ModelElement representedElement = childNode.RepresentedElement;
//            if (representedElement != null)
//            {
//                if (this.LookupNodeForElement(representedElement) != null)
//                {
//                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Microsoft.VisualStudio.Modeling.Shell.ModelExplorer.ModelExplorer.ErrorElementAlreadyInTree, new object[] { representedElement.ToString() }));
//                }
//                this.nodeLookup[representedElement] = childNode;
//            }
//            childNode.SetContainer(this);
//            childNode.Update();
//            this.InsertTreeNode(this.SubNodesOf(parentNode), childNode);
//        }

//        /// <summary>
//        /// Method to insert the incoming node into the TreeNodeCollection. This allows the derived class to change the sorting behavior.
//        /// N.B. This should really be protected, and is only intended as an override point. Do not call it directly, but rather call
//        /// InsertNode()
//        /// </summary>
//        /// <param name="siblingNodes"></param>
//        /// <param name="node"></param>
//        public virtual void InsertTreeNode(TreeNodeCollection siblingNodes, ExplorerTreeNode node)
//        {
//            if (siblingNodes == null)
//            {
//                throw new ArgumentNullException("siblingNodes");
//            }
//            if (node == null)
//            {
//                throw new ArgumentNullException("node");
//            }
//            if (node.Parent != null)
//            {
//                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Microsoft.VisualStudio.Modeling.Shell.ModelExplorer.ModelExplorer.NodeAlreadyInTree, new object[] { node.ToString() }), "node");
//            }
//            int count = siblingNodes.Count;
//            int index = 0;
//            if (count != 0)
//            {
//                index = 0;
//                while (index < count)
//                {
//                    ExplorerTreeNode node2 = siblingNodes[index] as ExplorerTreeNode;
//                    if ((node2 != null) && (string.Compare(node.Text, node2.Text, StringComparison.CurrentCulture) < 0))
//                    {
//                        break;
//                    }
//                    index++;
//                }
//            }
//            siblingNodes.Insert(index, node);
//        }

//        /// <summary>
//        /// Query whether the specified role should be considered a candidate for addition through the explorer
//        /// add menus.
//        /// </summary>
//        /// <param name="element">The ModelElement into which a new child element would be merged</param>
//        /// <param name="role">DomainRoleInfo describing the role</param>
//        /// <returns>True if the role is a candidate for addition, else false</returns>
//        /// <remarks>By default only non-abstract embedded elements are addable, with the exception of the 
//        /// extensions. Can be overridden, but it is not recommended to include relationships that are not embeddings,
//        /// as the explorer makes a general assumption that it is only adding through embeddings and its behaviour is 
//        /// undefined if this is not the case</remarks>
//        protected internal virtual bool IsAddableRoleForElement(ModelElement element, DomainRoleInfo role)
//        {
//            return this.IsExplorableRoleForElement(element, role);
//        }

//        /// <summary>
//        /// Query whether the specified role should be considered a candidate for display in the explorer.
//        /// It may not be displayed in the explorer if hidden.
//        /// </summary>
//        /// <param name="element">ModelElement under whose node the role would be displayed</param>
//        /// <param name="role">DomainRoleInfo describing the role</param>
//        /// <returns>True if the role is a candidate for display, else false</returns>
//        /// <remarks>By default only non-abstract embeddings are represented. Can be overridden, but it is not recommended
//        /// to include relationships that are not embeddings, as the explorer makes a general assumption
//        /// that it is only displaying embeddings and its behaviour is undefined if this is not the case</remarks>
//        protected internal virtual bool IsExplorableRoleForElement(ModelElement element, DomainRoleInfo role)
//        {
//            return (role.IsEmbedding && !role.DomainRelationship.ImplementationClass.IsAbstract);
//        }

//        private ExplorerTreeNode LookupNodeForElement(ModelElement element)
//        {
//            return (ExplorerTreeNode)this.nodeLookup[element];
//        }

//        /// <summary>
//        /// Got Focus
//        /// </summary>
//        /// <param name="e">Event args</param>
//        protected override void OnGotFocus(EventArgs e)
//        {
//            if (((this.ObjectModelBrowser != null) && (this.ObjectModelBrowser.Handle != IntPtr.Zero)) && this.ObjectModelBrowser.Visible)
//            {
//                this.ObjectModelBrowser.Focus();
//            }
//        }

//        /// <summary>
//        /// Command handler for menu Add commands
//        /// </summary>
//        /// <param name="sender"></param>
//        /// <param name="e"></param>
//        private void OnMenuAddModelElement(object sender, EventArgs e)
//        {
//            AddModelElementMenuCommand command = sender as AddModelElementMenuCommand;
//            if (command != null)
//            {
//                ModelElement element = command.Fire();
//                if (element != null)
//                {
//                    this.EnsureVisibleAndSelectElementNode(element);
//                }
//            }
//        }

//        /// <summary>
//        /// Eventhandler for handling when the Delete menu is selected from Visual Studio
//        /// </summary>
//        private void OnMenuDelete(object sender, EventArgs e)
//        {
//            this.ProcessOnMenuDeleteCommand();
//        }

//        /// <summary>
//        /// Eventhandler for handling when the DeleteAll menu is selected from Visual Studio
//        /// </summary>
//        private void OnMenuDeleteAll(object sender, EventArgs e)
//        {
//            this.ProcessOnMenuDeleteAllCommand();
//        }

//        /// <summary>
//        /// Eventhandler for handling when the Properities menu is selected from Visual Studio
//        /// </summary>
//        private void OnMenuProperties(object sender, EventArgs e)
//        {
//            this.ProcessOnMenuPropertiesCommand();
//        }

//        /// <summary>
//        /// Dynamic command status query handler for Add commands.
//        /// </summary>
//        /// <param name="sender"></param>
//        /// <param name="e"></param>
//        /// <remarks>Unlike the other status handlers this is not delegated to an overridable
//        /// command handler because the extension point here would be to replace the entire 
//        /// add command.</remarks>
//        private void OnStatusAddModelElement(object sender, EventArgs e)
//        {
//            AddModelElementMenuCommand command = sender as AddModelElementMenuCommand;
//            if (command != null)
//            {
//                command.QueryStatus();
//            }
//        }

//        /// <summary>
//        /// Eventhandler for handling when the Delete menu is about to be invoked from Visual Studio
//        /// </summary>
//        /// <param name="sender"></param>
//        /// <param name="e"></param>
//        private void OnStatusDelete(object sender, EventArgs e)
//        {
//            MenuCommand cmd = (MenuCommand)sender;
//            this.ProcessOnStatusDeleteCommand(cmd);
//        }

//        /// <summary>
//        /// Eventhandler for handling when the Delete All menu is about to be invoked from Visual Studio
//        /// </summary>
//        private void OnStatusDeleteAll(object sender, EventArgs e)
//        {
//            MenuCommand cmd = (MenuCommand)sender;
//            this.ProcessOnStatusDeleteAllCommand(cmd);
//        }

//        /// <summary>
//        /// Eventhandler for handling when the Properties menu is about to be invoked from Visual Studio
//        /// </summary>
//        private void OnStatusProperties(object sender, EventArgs e)
//        {
//            MenuCommand cmd = (MenuCommand)sender;
//            this.ProcessOnStatusPropertiesCommand(cmd);
//        }

//        /// <summary>
//        /// Virtual method to process the menu DeleteAll operation
//        /// </summary>
//        protected virtual void ProcessOnMenuDeleteAllCommand()
//        {
//            IList<ModelElement> childrenOfSelectedRoleGroup = this.GetChildrenOfSelectedRoleGroup();
//            if (childrenOfSelectedRoleGroup.Count > 0)
//            {
//                string name = string.Format(CultureInfo.CurrentCulture, ShellStrings.ModelExplorerDeleteAllUndoText, new object[] { this.SelectedRole.DisplayName });
//                using (Transaction transaction = this.store.TransactionManager.BeginTransaction(name))
//                {
//                    foreach (ModelElement element in childrenOfSelectedRoleGroup.Reverse<ModelElement>())
//                    {
//                        element.Delete();
//                    }
//                    transaction.Commit();
//                }
//            }
//        }

//        /// <summary>
//        /// Virtual method to process the menu Delete operation
//        /// </summary>
//        protected virtual void ProcessOnMenuDeleteCommand()
//        {
//            ModelElement selectedElement = this.SelectedElement;
//            if ((this.store != null) && (selectedElement != null))
//            {
//                string name = null;
//                if (!DomainClassInfo.TryGetName(selectedElement, out name))
//                {
//                    name = selectedElement.GetDomainClass().DisplayName;
//                }
//                string str2 = string.Format(CultureInfo.CurrentCulture, ShellStrings.ModelExplorerDeleteUndoText, new object[] { name });
//                using (Transaction transaction = this.store.TransactionManager.BeginTransaction(str2))
//                {
//                    selectedElement.Delete();
//                    transaction.Commit();
//                }
//            }
//        }

//        /// <summary>
//        /// Virtual method to process the menu Properties operation
//        /// </summary>
//        protected virtual void ProcessOnMenuPropertiesCommand()
//        {
//            Guid propertyBrowser = StandardToolWindows.PropertyBrowser;
//            IVsUIShell service = this.ServiceProvider.GetService(typeof(IVsUIShell)) as IVsUIShell;
//            if (service != null)
//            {
//                IVsWindowFrame frame;
//                ErrorHandler.ThrowOnFailure(service.FindToolWindow(0x80000, ref propertyBrowser, out frame));
//                if (frame != null)
//                {
//                    ErrorHandler.ThrowOnFailure(frame.Show());
//                }
//            }
//        }

//        /// <summary>
//        /// Virtual method for processing the DeleteAll menu status handler. 
//        /// </summary>
//        /// <param name="cmd">Menu command called from the Visual Studio</param>
//        /// <remarks>By default the DeleteAll command is enabled when a role group node with children
//        /// is selected.</remarks>
//        protected virtual void ProcessOnStatusDeleteAllCommand(MenuCommand cmd)
//        {
//            cmd.Visible = cmd.Enabled = this.ElementOperations.CanDelete(this.GetChildrenOfSelectedRoleGroup(), new Guid[0]);
//        }

//        /// <summary>
//        /// Virtual method for processing the Delete menu status handler. 
//        /// </summary>
//        /// <param name="cmd">Menu command called from the Visual Studio</param>
//        /// <remarks>Default is to enable when any node representing an element that is not a root is selected</remarks>
//        protected virtual void ProcessOnStatusDeleteCommand(MenuCommand cmd)
//        {
//            cmd.Visible = cmd.Enabled = this.CanDelete(this.SelectedElement);
//        }

//        /// <summary>
//        /// Virtual method for processing the Properties menu status handler. 
//        /// </summary>
//        /// <param name="cmd">Menu command called from the Visual Studio</param>
//        protected virtual void ProcessOnStatusPropertiesCommand(MenuCommand cmd)
//        {
//            cmd.Visible = cmd.Enabled = this.SelectedElement != null;
//        }

//        /// <summary>
//        /// Prune the tree *below* the specified node
//        /// </summary>
//        /// <param name="parentNode">TreeNode</param>
//        internal void PruneTree(ExplorerTreeNode parentNode)
//        {
//            List<ExplorerTreeNode> list = new List<ExplorerTreeNode>();
//            foreach (ExplorerTreeNode node in this.SubNodesOf(parentNode))
//            {
//                if (node.KeepNode)
//                {
//                    node.KeepNode = false;
//                    this.PruneTree(node);
//                }
//                else
//                {
//                    list.Add(node);
//                }
//            }
//            foreach (ExplorerTreeNode node2 in list)
//            {
//                this.RemoveNode(node2);
//            }
//        }

//        /// <summary>
//        /// Refresh the contents of the tree from the model.
//        /// </summary>
//        public void RefreshBrowserView()
//        {
//            ExplorerTreeNode selectedNode = this.SelectedNode;
//            this.UpdateRootElements();
//            this.ObjectModelBrowser.BeginUpdate();
//            for (int i = 0; i < this.RootElements.Count; i++)
//            {
//                ModelElement rootElement = this.RootElements[i] as ModelElement;
//                if (this.IsValidDocData)
//                {
//                    new DslModelExplorerWalker(this.ElementVisitor, this.ElementVisitorFilter, this.VisitRelationships).DoTraverse(rootElement);
//                }
//                if (rootElement.IsDeleted)
//                {
//                    this.RemoveRootElement(rootElement);
//                    i--;
//                }
//            }
//            this.PruneTree(null);
//            for (int j = 0; j < this.RootNodes.Count; j++)
//            {
//                TreeNode node2 = this.RootNodes[j];
//                if (!node2.IsExpanded)
//                {
//                    node2.Expand();
//                }
//            }
//            if (((selectedNode != null) && (this.SelectedNode != selectedNode)) && (selectedNode.Container == this))
//            {
//                this.ObjectModelBrowser.SelectedNode = selectedNode;
//            }
//            else
//            {
//                this.UpdateSelection(this.SelectedNode);
//            }
//            this.ObjectModelBrowser.EndUpdate();
//        }

//        /// <summary>
//        /// Remove a node from the tree
//        /// </summary>
//        /// <param name="deadNode">Node to remove</param>
//        /// <remarks>This method must be used to remove nodes from the tree, as otherwise
//        /// the internal state of the explorer will not be correctly maintained.</remarks>
//        public void RemoveNode(ExplorerTreeNode node)
//        {
//            ExplorerTreeNode nextNode;
//            for (ExplorerTreeNode node2 = (ExplorerTreeNode)node.FirstNode; node2 != null; node2 = nextNode)
//            {
//                nextNode = (ExplorerTreeNode)node2.NextNode;
//                this.RemoveNode(node2);
//            }
//            node.Remove();
//            if (node.RepresentedElement != null)
//            {
//                this.nodeLookup.Remove(node.RepresentedElement);
//            }
//            node.Dispose();
//        }

//        /// <summary>
//        /// Remove Root Element
//        /// </summary>
//        /// <param name="rootElement">Root</param>
//        /// <remarks>Does not remove the corresponding tree from the explorer until RefreshBrowserView() is called.</remarks>
//        public void RemoveRootElement(ModelElement rootElement)
//        {
//            if ((this.rootElements != null) && this.rootElements.Contains(rootElement))
//            {
//                this.rootElements.Remove(rootElement);
//            }
//        }

//        /// <summary>
//        /// The element represented by a node is being changed. Update the tree's
//        /// internal state to match.
//        /// </summary>
//        /// <param name="node"></param>
//        /// <param name="newElement"></param>
//        internal void SetNodeElement(ExplorerTreeNode node, ModelElement newElement)
//        {
//            ModelElement representedElement = node.RepresentedElement;
//            if ((representedElement != newElement) && (node.TreeView != null))
//            {
//                if (representedElement != null)
//                {
//                    this.nodeLookup.Remove(representedElement);
//                }
//                if (newElement != null)
//                {
//                    this.nodeLookup[newElement] = node;
//                }
//            }
//        }

//        /// <summary>
//        /// Helper method to show a context menu at the given coordinates.
//        /// </summary>
//        private void ShowContextMenu(int x, int y)
//        {
//            CommandID contextMenuCommandId = this.ContextMenuCommandId;
//            if (contextMenuCommandId.Guid != Guid.Empty)
//            {
//                IMenuCommandService service = (IMenuCommandService)this.serviceProvider.GetService(typeof(IMenuCommandService));
//                if (service != null)
//                {
//                    service.ShowContextMenu(contextMenuCommandId, x, y);
//                }
//            }
//        }

//        private TreeNodeCollection SubNodesOf(ExplorerTreeNode parentNode)
//        {
//            if (parentNode == null)
//            {
//                return this.RootNodes;
//            }
//            return parentNode.Nodes;
//        }

//        /// <summary>
//        /// Subscribe IMS events
//        /// </summary>
//        /// <param name="newStore">Store</param>
//        protected virtual void SubscribeToImsEvent(Store newStore)
//        {
//            if (newStore == null)
//            {
//                throw new ArgumentNullException("newStore");
//            }
//            newStore.EventManagerDirectory.ElementEventsEnded.Add(new EventHandler<ElementEventsEndedEventArgs>(this.ElementEventsEndedEventHandlerImpl));
//        }

//        /// <summary>
//        /// Virtual method to indicate tree node text has been changed.
//        /// </summary>
//        /// <param name="node"></param>
//        public virtual void TreeNodeTextChanged(ExplorerTreeNode node)
//        {
//            if (node != null)
//            {
//                TreeNode parent = node.Parent;
//                if ((parent != null) && parent.Nodes.Contains(node))
//                {
//                    TreeNode selectedNode = this.ObjectModelBrowser.SelectedNode;
//                    parent.Nodes.Remove(node);
//                    this.InsertTreeNode(parent.Nodes, node);
//                    if (selectedNode == node)
//                    {
//                        this.ObjectModelBrowser.SelectedNode = node;
//                    }
//                }
//            }
//        }

//        /// <summary>
//        /// After Select
//        /// </summary>
//        /// <param name="sender">Sender</param>
//        /// <param name="e">Event args</param>
//        private void TreeViewAfterSelectEvent(object sender, TreeViewEventArgs e)
//        {
//            this.UpdateSelection(e.Node as ExplorerTreeNode);
//        }

//        /// <summary>
//        /// Prevent root node from being collapsed.
//        /// </summary>
//        private void TreeViewBeforeCollapse(object sender, TreeViewCancelEventArgs e)
//        {
//            if (e.Node.Level == 0)
//            {
//                e.Cancel = true;
//            }
//        }

//        /// <summary>
//        /// Control loses focus
//        /// </summary>
//        /// <param name="obj"></param>
//        /// <param name="e"></param>
//        private void TreeViewLostFocus(object obj, EventArgs e)
//        {
//            if (this.addModelElementMenuCommand != null)
//            {
//                this.addModelElementMenuCommand.ResetValidAddTypes();
//            }
//        }

//        /// <summary>
//        /// Set selection on a right-click.
//        /// </summary>
//        /// <param name="sender"></param>
//        /// <param name="e"></param>
//        private void TreeViewOnMouseDown(object sender, MouseEventArgs e)
//        {
//            if ((e.Button == MouseButtons.Right) && (this.ObjectModelBrowser.GetNodeAt(e.X, e.Y) != null))
//            {
//                this.ObjectModelBrowser.SelectedNode = this.ObjectModelBrowser.GetNodeAt(e.X, e.Y);
//            }
//        }

//        /// <summary>
//        /// Unsubscribe IMS events
//        /// </summary>
//        /// <param name="oldStore">Store</param>
//        protected virtual void UnsubscribeToImsEvent(Store oldStore)
//        {
//            if (oldStore != null)
//            {
//                oldStore.EventManagerDirectory.ElementEventsEnded.Remove(new EventHandler<ElementEventsEndedEventArgs>(this.ElementEventsEndedEventHandlerImpl));
//            }
//        }

//        private void UpdateRootElements()
//        {
//            this.rootElements = (from r in this.FindRootElements(this.store).OfType<ModelElement>()
//                                 where !(r is PresentationElement)
//                                 select r).Distinct<ModelElement>().ToList<ModelElement>();
//        }

//        private void UpdateSelection(ExplorerTreeNode node)
//        {
//            if ((node != null) && (node.RepresentedElement != null))
//            {
//                this.SelectionService.SetSelectedComponents(new object[] { node.RepresentedElement });
//            }
//            else
//            {
//                this.SelectionService.SetSelectedComponents(null);
//            }
//            if (this.addModelElementMenuCommand != null)
//            {
//                this.addModelElementMenuCommand.ResetValidAddTypes();
//            }
//        }

//        /// <summary>
//        /// Process window messages.
//        /// </summary>
//        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode), SecurityPermission(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
//        protected override void WndProc(ref Message m)
//        {
//            try
//            {
//                if (m.Msg == 0x7b)
//                {
//                    IVsUIShell service = this.ServiceProvider.GetService(typeof(IVsUIShell)) as IVsUIShell;
//                    if (service != null)
//                    {
//                        service.RefreshPropertyBrowser(-1);
//                    }
//                    if (m.LParam.ToInt32() != -1)
//                    {
//                        this.ShowContextMenu(NativeMethods.SignedLOWORD((int)m.LParam), NativeMethods.SignedHIWORD((int)m.LParam));
//                    }
//                    else if ((this.ObjectModelBrowser != null) && (this.SelectedNode != null))
//                    {
//                        Rectangle bounds = this.SelectedNode.Bounds;
//                        Point point = this.ObjectModelBrowser.PointToScreen(bounds.Location);
//                        this.ShowContextMenu(point.X, point.Y);
//                    }
//                }
//                else
//                {
//                    base.WndProc(ref m);
//                }
//            }
//            catch (Exception exception)
//            {
//                if ((exception != CheckoutException.Canceled) && CriticalException.ThrowOrShow(this.serviceProvider, exception))
//                {
//                    throw;
//                }
//            }
//        }

//        /// <summary>
//        /// Specifies the context menu that should be shown for the model explorer.
//        /// </summary>
//        protected virtual CommandID ContextMenuCommandId
//        {
//            [DebuggerStepThrough]
//            get
//            {
//                return new CommandID(Guid.Empty, 0);
//            }
//        }

//        /// <summary>
//        /// Returns the parent of the model element currently selected in the explorer window.  Returns null if 
//        /// there is no parent.
//        /// </summary>
//        protected ModelElement CurrentParentElement
//        {
//            get
//            {
//                ExplorerTreeNode selectedNode = this.SelectedNode;
//                if (selectedNode != null)
//                {
//                    ExplorerTreeNode parent = selectedNode.Parent as ExplorerTreeNode;
//                    if (parent != null)
//                    {
//                        return parent.RepresentedElement;
//                    }
//                }
//                return null;
//            }
//        }

//        /// <summary>
//        /// Returns the current diagram 
//        /// </summary>
//        protected virtual ElementOperations ElementOperations
//        {
//            get
//            {
//                ModelingDocData modelingDocData = this.ModelingDocData;
//                if (modelingDocData == null)
//                {
//                    return null;
//                }
//                foreach (ModelingDocView view in modelingDocData.DocViews)
//                {
//                    DiagramDocView view2 = view as DiagramDocView;
//                    if ((view2 != null) && (view2.CurrentDiagram != null))
//                    {
//                        return view2.CurrentDiagram.ElementOperations;
//                    }
//                }
//                return new ElementOperations(modelingDocData, (modelingDocData.RootElement != null) ? modelingDocData.RootElement.Partition : modelingDocData.Store.DefaultPartition);
//            }
//        }

//        /// <summary>
//        /// Element Visitor
//        /// </summary>
//        public IElementVisitor ElementVisitor
//        {
//            [DebuggerStepThrough]
//            get
//            {
//                if (this.elementVisitor == null)
//                {
//                    this.elementVisitor = this.CreateElementVisitor();
//                }
//                return this.elementVisitor;
//            }
//            set
//            {
//                this.elementVisitor = value;
//            }
//        }

//        /// <summary>
//        /// Element Visitor Filter
//        /// </summary>
//        public IElementVisitorFilter ElementVisitorFilter
//        {
//            [DebuggerStepThrough]
//            get
//            {
//                if (this.elementVisitorFilter == null)
//                {
//                    this.elementVisitorFilter = this.CreateElementVisitorFilter();
//                }
//                return this.elementVisitorFilter;
//            }
//            set
//            {
//                this.elementVisitorFilter = value;
//            }
//        }

//        /// <summary>
//        /// Returns the event handler which allows the derived class to supply tree node display name
//        /// </summary>
//        public GetModelElementDisplayNameEventHandler GetModelElementDisplayNameEventHandler
//        {
//            [DebuggerStepThrough]
//            get
//            {
//                return this.getModelElementDisplayNameEventHandler;
//            }
//            [DebuggerStepThrough]
//            protected set
//            {
//                this.getModelElementDisplayNameEventHandler = value;
//            }
//        }

//        /// <summary>
//        /// Is the DocData valid (do we care about it?)
//        /// </summary>
//        [CLSCompliant(false)]
//        protected virtual bool IsValidDocData
//        {
//            [DebuggerStepThrough]
//            get
//            {
//                return true;
//            }
//        }

//        /// <summary>
//        /// DocData
//        /// </summary>
//        [CLSCompliant(false)]
//        public ModelingDocData ModelingDocData
//        {
//            [DebuggerStepThrough]
//            get
//            {
//                return this.modelingDocData;
//            }
//            set
//            {
//                if (this.modelingDocData != value)
//                {
//                    this.modelingDocData = value;
//                    Store newStore = ((this.modelingDocData != null) && this.IsValidDocData) ? this.ModelingDocData.Store : null;
//                    this.ExploreStore(newStore);
//                }
//            }
//        }

//        /// <summary>
//        /// Selection
//        /// </summary>
//        public TreeView ObjectModelBrowser
//        {
//            [DebuggerStepThrough]
//            get
//            {
//                if (this.objectModelBrowser == null)
//                {
//                    this.objectModelBrowser = new TreeView();
//                }
//                return this.objectModelBrowser;
//            }
//        }

//        /// <summary>
//        /// Returns the root elements domain class Id. The is the very top level tree node in the TreeView
//        /// </summary>
//        protected virtual Guid RootElementDomainClassId
//        {
//            get
//            {
//                return Guid.Empty;
//            }
//        }

//        /// <summary>
//        /// Root Elements
//        /// </summary>
//        public IList RootElements
//        {
//            [DebuggerStepThrough]
//            get
//            {
//                if (this.rootElements == null)
//                {
//                    this.rootElements = new List<ModelElement>();
//                }
//                return ArrayList.ReadOnly(this.rootElements);
//            }
//        }

//        private TreeNodeCollection RootNodes
//        {
//            get
//            {
//                return this.ObjectModelBrowser.Nodes;
//            }
//        }

//        /// <summary>
//        /// Returns the model element currently selected in the explorer window.  Returns null if 
//        /// no model element is selected.
//        /// </summary>
//        protected ModelElement SelectedElement
//        {
//            get
//            {
//                ExplorerTreeNode selectedNode = this.SelectedNode;
//                if (selectedNode != null)
//                {
//                    return selectedNode.RepresentedElement;
//                }
//                return null;
//            }
//        }

//        private ExplorerTreeNode SelectedNode
//        {
//            get
//            {
//                return (this.ObjectModelBrowser.SelectedNode as ExplorerTreeNode);
//            }
//        }

//        /// <summary>
//        /// Returns the role currently selected in the explorer window.  Returns null if 
//        /// no role is selected.
//        /// </summary>
//        protected DomainRoleInfo SelectedRole
//        {
//            get
//            {
//                ExplorerTreeNode selectedNode = this.SelectedNode;
//                if (selectedNode != null)
//                {
//                    return selectedNode.RepresentedRole;
//                }
//                return null;
//            }
//        }

//        /// <summary>
//        /// Selection
//        /// </summary>
//        protected ISelectionService SelectionService
//        {
//            [DebuggerStepThrough]
//            get
//            {
//                if (this.selectionService == null)
//                {
//                    this.selectionService = this.serviceProvider.GetService(typeof(ISelectionService)) as ISelectionService;
//                }
//                return this.selectionService;
//            }
//        }

//        /// <summary>
//        /// ServiceProvider
//        /// </summary>
//        protected IServiceProvider ServiceProvider
//        {
//            [DebuggerStepThrough]
//            get
//            {
//                return this.serviceProvider;
//            }
//        }

//        /// <summary>
//        /// Table mapping ModelElements to the ExplorerTreeNode which represents them
//        /// </summary>
//        /// <remarks>Remains an untyped HashTable for backwards compatibility as exposed 
//        /// through ExplorerElementVisitor.TreeNodeHash property</remarks>
//        internal Hashtable TreeNodeHash
//        {
//            get
//            {
//                return this.nodeLookup;
//            }
//        }

//        /// <summary>
//        /// Indicates whether relationships (links) should be included as part of the element traversal.
//        /// The default value is true.
//        /// </summary>
//        protected virtual bool VisitRelationships
//        {
//            get
//            {
//                return true;
//            }
//        }

//        /// <summary>
//        /// AddModelElement dynamic item start command.
//        /// </summary>
//        private sealed class AddModelElementMenuCommand : DynamicStatusMenuCommand
//        {
//            private List<DomainClassInfo> addableTypes;
//            private DomainClassInfo currentRolePlayer;
//            private ModelExplorerTreeContainer parentContainer;

//            public AddModelElementMenuCommand(ModelExplorerTreeContainer parentContainer, EventHandler statusHandler, EventHandler execHandler)
//                : base(statusHandler, execHandler, CommonModelingCommands.ModelExplorerAddModelElement)
//            {
//                this.addableTypes = new List<DomainClassInfo>();
//                this.parentContainer = parentContainer;
//                this.ResetMatchedCommandId();
//            }

//            private void BuildAddableTypes(ElementOperations elemOps, ModelElement selectedElement)
//            {
//                this.currentRolePlayer = selectedElement.GetDomainClass();
//                HashSet<DomainClassInfo> addable = new HashSet<DomainClassInfo>();
//                this.DetermineAddableTypes(selectedElement, elemOps, addable);
//                this.DetermineAddableSupplementaryTypes(selectedElement, elemOps, addable);
//                this.addableTypes = addable.ToList<DomainClassInfo>();
//                this.SortAddableTypes();
//            }

//            /// <summary>
//            /// Determine whether a new isntance of a specific type is mergeable under a specified parent element.
//            /// </summary>
//            /// <returns>true if an instance of the type can be added to the parent.</returns>
//            private static bool CanMergeChildTypeUnderParentElement(ElementOperations elemOps, ModelElement parentElement, DomainClassInfo childInfo)
//            {
//                if (childInfo.ImplementationClass.IsAbstract)
//                {
//                    return false;
//                }
//                ElementGroupPrototype elementGroupPrototype = new ElementGroupPrototype(parentElement.Partition, childInfo.Id);
//                return elemOps.CanMergeElementGroupPrototype(parentElement, elementGroupPrototype);
//            }

//            private ModelElement CreateChildElementAndLink(ModelElement parent, DomainClassInfo childClass)
//            {
//                ModelElement element = null;
//                ElementOperations elementOperations = this.parentContainer.ElementOperations;
//                if (elementOperations != null)
//                {
//                    ElementGroupPrototype elementGroupPrototype = new ElementGroupPrototype(parent.Partition, childClass.Id);
//                    Partition partition = elementOperations.ChooseMergeTarget(parent, elementGroupPrototype).Partition;
//                    element = partition.ElementFactory.CreateElement(childClass);
//                    ElementGroup elementGroup = new ElementGroup(partition);
//                    elementGroup.Add(element);
//                    elementGroup.MarkAsRoot(element);
//                    elementOperations.MergeElementGroup(parent, elementGroup);
//                }
//                return element;
//            }

//            private void DetermineAddableSupplementaryTypes(ModelElement element, ElementOperations elemOps, HashSet<DomainClassInfo> addable)
//            {
//                foreach (ExtensionElement element2 in element.GetAllExtensions())
//                {
//                    this.DetermineAddableTypes(element2, elemOps, addable);
//                }
//            }

//            private void DetermineAddableTypes(ModelElement element, ElementOperations elemOps, HashSet<DomainClassInfo> addable)
//            {
//                foreach (DomainRoleInfo info in from eachRole in element.GetDomainClass().AllDomainRolesPlayed
//                                                where this.parentContainer.IsAddableRoleForElement(element, eachRole)
//                                                select eachRole)
//                {
//                    if (!info.IsOne || (DomainRoleInfo.GetLinkedElement(element, info.Id) == null))
//                    {
//                        DomainClassInfo rolePlayer = info.OppositeDomainRole.RolePlayer;
//                        IncludeAddableType(element, rolePlayer, elemOps, addable);
//                        foreach (DomainClassInfo info3 in rolePlayer.AllDescendants)
//                        {
//                            IncludeAddableType(element, info3, elemOps, addable);
//                        }
//                        continue;
//                    }
//                }
//            }

//            /// <summary>
//            /// Match command id against types from the addable list.
//            /// </summary>
//            /// <param name="cmdId">Next command id for the list</param>
//            /// <returns>true if proposed command id would be within the bounds of the list, else false</returns>
//            public override bool DynamicItemMatch(int cmdId)
//            {
//                int num = cmdId - this.CommandID.ID;
//                if ((num >= 0) && (num < this.AddableTypes.Count))
//                {
//                    base.MatchedCommandId = cmdId;
//                    return true;
//                }
//                this.ResetMatchedCommandId();
//                return false;
//            }

//            /// <summary>
//            /// Fire the add command to merge in a new element of the currently matching type
//            /// </summary>
//            /// <returns></returns>
//            internal ModelElement Fire()
//            {
//                DomainClassInfo childClass = this.AddableTypes.ElementAtOrDefault<DomainClassInfo>(base.MatchedCommandId - this.CommandID.ID);
//                ModelElement selectedElement = this.parentContainer.SelectedElement;
//                ModelElement element2 = null;
//                if ((childClass != null) && (selectedElement != null))
//                {
//                    string name = string.Format(CultureInfo.CurrentCulture, ShellStrings.ModelExplorerAddElementUndoText, new object[] { childClass.DisplayName });
//                    Transaction transaction = selectedElement.Store.TransactionManager.BeginTransaction(name);
//                    try
//                    {
//                        element2 = this.CreateChildElementAndLink(selectedElement, childClass);
//                        transaction.Commit();
//                    }
//                    catch (OperationCanceledException)
//                    {
//                        int transactionDepth = transaction.TransactionDepth;
//                        transaction.Rollback();
//                        if (transactionDepth != 1)
//                        {
//                            throw;
//                        }
//                        element2 = null;
//                    }
//                    finally
//                    {
//                        if (transaction != null)
//                        {
//                            transaction.Dispose();
//                        }
//                    }
//                    this.ResetValidAddTypes();
//                }
//                this.ResetMatchedCommandId();
//                return element2;
//            }

//            private static void IncludeAddableType(ModelElement element, DomainClassInfo rolePlayer, ElementOperations elemOps, HashSet<DomainClassInfo> addable)
//            {
//                if (!addable.Contains(rolePlayer) && CanMergeChildTypeUnderParentElement(elemOps, element, rolePlayer))
//                {
//                    addable.Add(rolePlayer);
//                }
//            }

//            /// <summary>
//            /// Query status of the dynamic Add command.
//            /// </summary>
//            /// <remarks>The first context menu item in the resource file has the DYNAMICITEMSTART
//            /// flag. The host will QueryStatus us for successive commands beginning with
//            /// that one until we return one that's not supported. The context menu will
//            /// be built from the list of valid items.</remarks>
//            internal void QueryStatus()
//            {
//                DomainClassInfo info = this.AddableTypes.ElementAtOrDefault<DomainClassInfo>(base.MatchedCommandId - this.CommandID.ID);
//                if (info != null)
//                {
//                    this.Text = string.Format(CultureInfo.CurrentCulture, ShellStrings.ModelExplorerAddElementCommandText, new object[] { "&" + info.DisplayName });
//                    this.Supported = this.Visible = this.Enabled = true;
//                    this.ResetMatchedCommandId();
//                }
//                else
//                {
//                    this.Visible = this.Enabled = false;
//                }
//            }

//            private int ResetMatchedCommandId()
//            {
//                int num;
//                base.MatchedCommandId = num = this.CommandID.ID;
//                return num;
//            }

//            /// <summary>
//            /// Reset the current list of addable types so that it is recalculated on demand.
//            /// </summary>
//            internal void ResetValidAddTypes()
//            {
//                this.currentRolePlayer = null;
//                this.addableTypes = new List<DomainClassInfo>();
//            }

//            private void SortAddableTypes()
//            {
//                this.addableTypes.Sort((Comparison<DomainClassInfo>)((c1, c2) => string.Compare(c1.DisplayName, c2.DisplayName, false, CultureInfo.CurrentUICulture)));
//            }

//            /// <summary>
//            /// Get a collection of DomainClassInfo's describing the types of domain object that can be merged into the selected
//            /// parent element. If there is no selection then the collection will be empty. The value is never null.
//            /// </summary>
//            private IList<DomainClassInfo> AddableTypes
//            {
//                get
//                {
//                    ElementOperations elementOperations = this.parentContainer.ElementOperations;
//                    if (elementOperations == null)
//                    {
//                        this.ResetValidAddTypes();
//                    }
//                    else
//                    {
//                        ModelElement selectedElement = this.parentContainer.SelectedElement;
//                        if (selectedElement != null)
//                        {
//                            if (this.currentRolePlayer != selectedElement.GetDomainClass())
//                            {
//                                this.BuildAddableTypes(elementOperations, selectedElement);
//                            }
//                        }
//                        else
//                        {
//                            this.ResetValidAddTypes();
//                        }
//                    }
//                    return this.addableTypes;
//                }
//            }
//        }
//    }



//}
